home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / net_src.arc / sys5_io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  8.4 KB  |  447 lines

  1. /* OS- and machine-dependent stuff for SYS5 */
  2.  
  3. /*
  4.     FILE: UNIX.io.c
  5.     
  6.     Routines:
  7.         ioinit()
  8.         iostop()
  9.         asy_init()
  10.         asy_stop()
  11.         asy_speed()
  12.         asy_output()
  13.         asy_recv()
  14.         dir()
  15.     Written or converted by Mikel Matthews, N9DVG
  16.     SYS5 added by Jere Sandidge, K4FUM
  17.     Directory pipe added by Ed DeHart, WA3YOA
  18.     Numerous changes by Charles Hedrick and John Limpert, N3DMC
  19.     Hell, *I* even hacked on it... :-)  Bdale, N3EUA
  20.     
  21.     If you want to use the select code, define SELECT in the makefile or
  22.     in this file.
  23. */
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <termio.h>
  28. #include <signal.h>
  29. #include <sys/file.h>
  30. #include <sys/dir.h>
  31. #include <time.h>
  32. #include <fcntl.h>
  33. #include "global.h"
  34. #include "asy.h"
  35. #include "mbuf.h"
  36. #include "internet.h"
  37. #include "iface.h"
  38. #include "unix.h"
  39. #include "cmdparse.h"
  40.  
  41. #ifndef    B19200
  42. #define    B19200    EXTA
  43. #endif
  44.  
  45. #ifndef    B38400
  46. #define    B38400    EXTB
  47. #endif
  48.  
  49. struct asy asy[ASY_MAX];
  50. struct interface *ifaces;
  51. struct termio mysavetty, savecon;
  52. int savettyfl;
  53. int    IORser[ASY_MAX];
  54. char *ttbuf;
  55. int slipisopen;
  56.  
  57.  
  58. /* Called at startup time to set up console I/O, memory heap */
  59. ioinit()
  60. {
  61.     struct termio ttybuf;
  62.     extern int iostop();
  63.  
  64.     (void) signal(SIGHUP, iostop);
  65.     (void) signal(SIGINT, iostop);
  66.     (void) signal(SIGQUIT, iostop);
  67.     (void) signal(SIGTERM, iostop);
  68.  
  69.     ioctl(0, TCGETA, &ttybuf);
  70.     savecon = ttybuf;
  71.  
  72.     ttybuf.c_iflag &= ~IXON;
  73.     ttybuf.c_lflag &= ~(ICANON|ISIG|ECHO);
  74.     ttybuf.c_cc[VTIME] = '\0';
  75.     ttybuf.c_cc[VMIN] = '\01';
  76.     if ((savettyfl = fcntl(0, F_GETFL, 0)) == -1) {
  77.         perror("Could not read console flags");
  78.         return -1;
  79.     }
  80.     fcntl(0, F_SETFL, savettyfl | O_NDELAY);
  81.  
  82.     ioctl(0, TCSETAW, &ttybuf);
  83. }
  84.  
  85.  
  86. /* Called just before exiting to restore console state */
  87. iostop()
  88. {
  89.     setbuf(stdout,NULLCHAR);
  90.  
  91.     while (ifaces != NULLIF) {
  92.         if (ifaces->stop != NULLFP)
  93.             (*ifaces->stop)(ifaces->dev);
  94.         ifaces = ifaces->next;
  95.     }
  96.  
  97.     ioctl(0, TCSETAW, &savecon);
  98.     fcntl(0, F_SETFL, savettyfl);
  99.     exit(0);
  100. }
  101.  
  102. /* Initialize asynch port "dev" */
  103. int
  104. asy_init(dev, arg1, arg2, bufsize)
  105. int16 dev;
  106. char *arg1, *arg2;
  107. unsigned bufsize;
  108. {
  109.     register struct asy *ap;
  110.     struct termio    sgttyb;
  111.  
  112. #ifdef    SYS5_DEBUG
  113.     printf("asy_init: called\n");
  114. #endif    /* SYS5_DEBUG */
  115.  
  116.     if (dev >= nasy)
  117.         return -1;
  118.  
  119.     ap = &asy[dev];
  120.     ap->tty = malloc(strlen(arg2)+1);
  121.     strcpy(ap->tty, arg2);
  122.     printf("asy_init: tty name = %s\n", ap->tty);
  123.  
  124.     if ((IORser[dev] = open(ap->tty, (O_RDWR|O_NDELAY), 0)) < 0) {
  125.         perror("Could not open device IORser");
  126.         return -1;
  127.     }
  128.  
  129.  /* 
  130.   * get the stty structure and save it 
  131.   */
  132.  
  133.     if (ioctl(IORser[dev], TCGETA, &mysavetty) < 0)    {
  134.         perror("ioctl failed on device");
  135.         return -1;
  136.     }
  137.  
  138.  /* 
  139.   * copy over the structure 
  140.   */
  141.  
  142.     sgttyb = mysavetty;
  143.     sgttyb.c_iflag = (IGNBRK | IGNPAR);
  144.     sgttyb.c_oflag = 0;
  145.     sgttyb.c_lflag = 0;
  146.     sgttyb.c_cflag = (B9600 | CS8 | CREAD);
  147.     sgttyb.c_cc[VTIME] = 0;
  148.     sgttyb.c_cc[VMIN] = 0;
  149.  
  150.     if (ioctl(IORser[dev], TCSETAF, &sgttyb) < 0) {
  151.         perror("ioctl could not set parameters for IORser");
  152.         return -1;
  153.     }
  154.  
  155.     return 0;
  156. }
  157.  
  158.  
  159. int
  160. asy_stop(dev)
  161. int dev;
  162. {
  163. }
  164.  
  165.  
  166. /* Set asynch line speed */
  167. int
  168. asy_speed(dev, speed)
  169. int dev;
  170. int speed;
  171. {
  172.     struct termio sgttyb;
  173.  
  174.     if (speed == 0 || dev >= nasy)
  175.         return -1;
  176.  
  177. #ifdef    SYS5_DEBUG
  178.     printf("asy_speed: Setting speed for device %d to %d\n",dev, speed);
  179. #endif
  180.  
  181.     asy[dev].speed = speed;
  182.  
  183.     if (ioctl(IORser[dev], TCGETA, &sgttyb) < 0) {
  184.         perror("ioctl could not set parameters");
  185.         return -1;
  186.     }
  187.  
  188.     sgttyb.c_cflag &= ~CBAUD;
  189.  
  190.     switch ((unsigned)speed) {
  191.     case 0:
  192.         sgttyb.c_cflag |= B0;
  193.         break;
  194.     case 50:
  195.         sgttyb.c_cflag |= B50;
  196.         break;
  197.     case 75:
  198.         sgttyb.c_cflag |= B75;
  199.         break;
  200.     case 110:
  201.         sgttyb.c_cflag |= B110;
  202.         break;
  203.     case 134:
  204.         sgttyb.c_cflag |= B134;
  205.         break;
  206.     case 150:
  207.         sgttyb.c_cflag |= B150;
  208.         break;
  209.     case 200:
  210.         sgttyb.c_cflag |= B200;
  211.         break;
  212.     case 300:
  213.         sgttyb.c_cflag |= B300;
  214.         break;
  215.     case 600:
  216.         sgttyb.c_cflag |= B600;
  217.         break;
  218.     case 1200:
  219.         sgttyb.c_cflag |= B1200;
  220.         break;
  221.     case 1800:
  222.         sgttyb.c_cflag |= B1800;
  223.         break;
  224.     case 2400:
  225.         sgttyb.c_cflag |= B2400;
  226.         break;
  227.     case 4800:
  228.         sgttyb.c_cflag |= B4800;
  229.         break;
  230.     case 9600:
  231.         sgttyb.c_cflag |= B9600;
  232.         break;
  233.     case 19200:
  234.         sgttyb.c_cflag |= B19200;
  235.         break;
  236.     case 38400:
  237.         sgttyb.c_cflag |= B38400;
  238.         break;
  239.     default:
  240.         printf("asy_speed: Unknown speed (%d)\n", speed);
  241.         break;
  242.     }
  243.  
  244. #ifdef    SYS5_DEBUG
  245.     printf("speed = %d\n", sgttyb.sg_ispeed);
  246. #endif    /* SYS5_DEBUG */
  247.  
  248.     if (ioctl(IORser[dev], TCSETAW, &sgttyb) < 0) {
  249.         perror("ioctl could not set parameters for IORser");
  250.         return -1;
  251.     }
  252.  
  253.     return 0;
  254. }
  255.  
  256.  
  257. /* Send a buffer to serial transmitter */
  258. asy_output(dev, buf, cnt)
  259. unsigned dev;
  260. char *buf;
  261. unsigned short cnt;
  262. {
  263. #ifdef    SYS5_DEBUG
  264.     printf("asy_output called. dev = %d, cnt = %d\n", dev, cnt);
  265.     printf("buf = %lx\n", (long) buf);
  266.     fflush(stdout);
  267. #endif
  268.     
  269.     if (dev >= nasy)
  270.         return -1;
  271.  
  272.     if (write(IORser[dev], buf, cnt) < cnt)    {
  273.         perror("asy_output");
  274.         printf("asy_output: error in writing to device %d\n", dev);
  275.         return -1;
  276.     }
  277.  
  278.     return 0;
  279. }
  280.  
  281. /* Receive characters from asynch line
  282.  * Returns count of characters read
  283.  */
  284. unsigned
  285. asy_recv(dev,buf,cnt)
  286. int dev;
  287. char *buf;
  288. unsigned cnt;
  289. {
  290. #define    IOBUFLEN    256
  291.     unsigned tot;
  292.     int r;
  293.     static struct    {
  294.         char    buf[IOBUFLEN];
  295.         char    *data;
  296.         int    cnt;
  297.     }    IOBUF[ASY_MAX];
  298.  
  299. #ifdef SELECT
  300.     int    mask;
  301.     int    writemask;
  302.     int    ok;
  303.     struct timeval timeout;
  304.     timeout.tv_sec = 0;
  305.     timeout.tv_usec = 35;
  306.     mask = (1<<IORser[dev]);
  307.     writemask = (1<<IORser[dev]);
  308.     ok = 0;
  309.     tot = 0;
  310.     ok = select(mask, &mask, 0, 0, &timeout);
  311.     if ( mask & (1<<IORser[dev]))
  312.     {
  313.         tot = read(IORser[dev], buf, cnt);
  314.     }
  315.     return (tot);
  316. #else
  317.     if(IORser[dev] < 0) {
  318.         printf("asy_recv: bad file descriptor passed for device %d\n",
  319.             dev);
  320.         return(0);
  321.     }
  322.     tot = 0;
  323.     /* fill the read ahead buffer */
  324. #ifdef notdef
  325.     if(IOBUF[dev].cnt == 0 && (rdchk(IORser[dev]) > 0)) {
  326. #else
  327.     if(IOBUF[dev].cnt == 0) {
  328. #endif
  329.         IOBUF[dev].data = IOBUF[dev].buf;
  330.         r = read(IORser[dev], IOBUF[dev].data, IOBUFLEN);
  331.         /* check the read */
  332.         if (r == -1) {
  333.             IOBUF[dev].cnt = 0;    /* bad read */
  334.             perror("asy_recv");
  335.             printf("asy_recv: error in reading from device %d\n", dev);
  336.             return(0);
  337.         } else
  338.             IOBUF[dev].cnt = r;
  339.     } 
  340.     r = 0;    /* return count */
  341.     /* fetch what you need with no system call overhead */
  342.     if(IOBUF[dev].cnt > 0) {
  343.         if(cnt == 1) { /* single byte copy, do it here */
  344.             *buf = *IOBUF[dev].data++;
  345.             IOBUF[dev].cnt--;
  346.             r = 1;
  347.         } else { /* multi-byte copy, left memcpy do the work */
  348.             unsigned n = min(cnt, IOBUF[dev].cnt);
  349.             memcpy(buf, IOBUF[dev].data, n);
  350.             IOBUF[dev].cnt -= n;
  351.             IOBUF[dev].data += n;
  352.             r = n;
  353.         }
  354.     }
  355.     tot = (unsigned int) r;
  356.     return (tot);
  357. #endif
  358. }
  359.  
  360. /* Generate a directory listing by opening a pipe to /bin/ls.
  361.  * If full == 1, give a full listing; else return just a list of names.
  362.  */
  363. FILE *
  364. dir(path,full)
  365. char *path;
  366. int full;
  367. {
  368.     FILE *fp;
  369.     char cmd[1024];
  370.  
  371.     if (path == NULLCHAR || path[0] == '\0')
  372.         path = ".";
  373.  
  374. #ifdef    SYS5_DEBUG
  375.     printf("DIR: path = %s\n", path);
  376. #endif    /* SYS5_DEBUG */
  377.  
  378.     if (full)
  379.         sprintf(cmd,"ls -l %s", path);
  380.     else
  381.         sprintf(cmd, "ls %s", path);
  382.  
  383.     if ((fp = popen(cmd,"r")) == NULLFILE) {
  384.         perror("popen");
  385.         return NULLFILE;
  386.     }
  387.  
  388.     return fp;
  389. }
  390.  
  391.  
  392. asy_ioctl(interface, argc, argv)
  393. struct interface *interface;
  394. int    argc;
  395. char    *argv[];
  396. {
  397.     if (argc < 1) {
  398.         printf("%d\r\n", asy[interface->dev].speed);
  399.         return 0;
  400.     }
  401.  
  402.     return asy_speed(interface->dev, atoi(argv[0]));
  403. }
  404.  
  405. int
  406. OpenPty()
  407. {
  408.     extern int    errno;
  409.     struct termio    ttybuf;
  410.     int        pty;
  411.     int        i, j;
  412.     int        tmaster;
  413.     int        letcnt=0, numcnt=0;
  414.  
  415.     static char    *letters = "pqrs",
  416.             *numbers = "0123456789abcdef";
  417. /*
  418.     static char    *letters = "p",
  419.             *numbers = "012";
  420. */
  421. #ifdef hpux
  422.     static char master[] = "/dev/ptym/ptyXX";
  423. #else
  424.     static char master[] = "/dev/ptyXX";
  425. #endif
  426.     static int    letmax, nummax;
  427.  
  428.     letmax=strlen(letters)-1, nummax=strlen(numbers)-1;
  429.     do {
  430. #ifdef hpux
  431.         master[strlen("/dev/ptym/pty")] = letters[letcnt];
  432.         master[strlen("/dev/ptym/ptyX")] = numbers[numcnt];
  433. #else
  434.         master[strlen("/dev/pty")] = letters[letcnt];
  435.         master[strlen("/dev/ptyX")] = numbers[numcnt];
  436. #endif
  437.         if (letcnt > letmax) {
  438.             return -1;
  439.         } else if (++numcnt > nummax) {
  440.             letcnt++;
  441.             numcnt = 0;
  442.         } 
  443.     } while ((pty=open(master, O_RDWR | O_NDELAY)) < 0);
  444.  
  445.     return(pty);
  446. }
  447.